Skip to content

fix: convert format parse errors from Internal Error to user-facing messages#1076

Open
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:fix/format-error-messages
Open

fix: convert format parse errors from Internal Error to user-facing messages#1076
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:fix/format-error-messages

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Motivation:
Jsonnet documents std.format(str, vals) as Python-style percent formatting, and documents the % operator as shorthand for std.format. Malformed percent-format specs are therefore user input errors, not interpreter failures.

Before this PR, sjsonnet's format scanner/lowering path could throw plain JVM exceptions for malformed specs such as %z, a trailing %, or an unterminated named label. Those exceptions surfaced as Internal Error with Java stack traces, while Python and other Jsonnet implementations report user-facing format/runtime errors.

Modification:

  • Add parseFormatOrFail around both cached format-string parsing and legacy lowered-format conversion.
  • Preserve existing sjsonnet Error values unchanged.
  • Convert NonFatal parser/lowering exceptions to Error.fail(..., pos) so malformed format specs are reported at the Jsonnet expression position.
  • Add regression tests for invalid conversions, truncated format specs, unterminated named labels, the % shorthand path, and representative successful formats.

Result:
Malformed format strings now produce user-facing sjsonnet errors instead of leaking Java stack traces. The % shorthand still uses the same formatting implementation; its diagnostic keeps the existing binary-operator stack shape, so it does not add a [std.format] builtin frame. The table below includes the old sjsonnet behavior from master before this PR.

Case Python % formatting C++ jsonnet observed go-jsonnet observed jrsonnet observed sjsonnet before this PR sjsonnet after this PR
std.format("%z", [1]) ValueError: unsupported format character z RUNTIME ERROR: Unrecognised conversion type: z RUNTIME ERROR: Unrecognised conversion type: z format error: unrecognized conversion type: z [std.format] Internal Error, caused by Unrecognized conversion type: z [std.format] Unrecognized conversion type: z
std.format("hello %", [1]) ValueError: incomplete format RUNTIME ERROR: Truncated format code. RUNTIME ERROR: Truncated format code. format error: truncated format code [std.format] Internal Error, caused by Truncated format code at end of string [std.format] Truncated format code at end of string
std.format("%(key", {key: 1}) ValueError: incomplete format key RUNTIME ERROR: Truncated format code. RUNTIME ERROR: Truncated format code. format error: truncated format code [std.format] Internal Error, caused by Unterminated ( in format spec [std.format] Unterminated ( in format spec
"%z" % [1] same malformed %z error RUNTIME ERROR: Unrecognised conversion type: z RUNTIME ERROR: Unrecognised conversion type: z format error: unrecognized conversion type: z Internal Error, caused by Unrecognized conversion type: z Unrecognized conversion type: z

References:

@He-Pin He-Pin marked this pull request as draft July 3, 2026 16:09
Motivation:
Jsonnet documents std.format as Python-style percent formatting and documents the %
operator as shorthand for std.format. Malformed percent-format specs are user input
errors: Python raises ValueError, and other Jsonnet implementations report runtime
format errors. sjsonnet's scanner/lowering path threw plain JVM exceptions for cases
such as "%z", a trailing "%", or an unterminated named label, which surfaced as
"Internal Error" with Java stack traces.

Modification:
Introduce parseFormatOrFail to wrap both cached format-string parsing and legacy
lowered-format conversion. Preserve existing sjsonnet Error values, but map NonFatal
parser/lowering exceptions to Error.fail at the format expression position. Add
regression coverage for std.format invalid conversions, truncated format specs,
unterminated named labels, the % shorthand path, and representative successful
formats.

Result:
Malformed format strings now produce user-facing sjsonnet errors without leaking Java
stack traces. The % shorthand continues to use the same formatting implementation while
keeping its existing operator stack shape. Verified with __.checkFormat,
sjsonnet.jvm[3.3.8].test, and sjsonnet.jvm[3.3.8].assembly.

References:
- https://jsonnet.org/ref/stdlib.html#std-format
- https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting
@He-Pin He-Pin force-pushed the fix/format-error-messages branch from adf999b to ae0293a Compare July 4, 2026 02:23
@He-Pin He-Pin marked this pull request as ready for review July 4, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant